// 插件形式的全局指令
// 插件+指令
// 1.回顾插件指令从2=>3 api的变化
// 2.实现插件的基础安装
// 3.实现指令的基础配置
// 4.实现图片懒加载核心逻辑

/*
  vue2. 中如何定义插件 如何注册插件?
  定义:
    1.对象定义
    const plugin = {
      install(Vue) {
        // 插件的逻辑
      }
    }
    2.函数定义
    function plugin(Vue) {
      // 插件的逻辑
    }
  注册:
    在Vue实例化之前 Vue.use(plugin),当调用use方法的时候i
    本质上是在执行插件的install方法
    并且同时把Vue构造函数本身当成实参传入到准备好的形参位置

    Vue.component() 全局组件注册
    Vue.directive() 全局指令注册
    Vue.prototype.$http = function() {} 原型挂载方法,每个组件都可以通过this取获取使用
*/

/*
  Vue3. 中如何定义插件 如何注册插件?
    定义:
      1.对象定义
      const plugin = {
        install(app) {
          //插件逻辑
        }
      }
      2.函数定义
      function plugin(app) {
        // 插件的逻辑
      }
    注册:
      createApp() -> app应用实例对象
      app.use(plugin)
      调用use方法的同时会把app实例对象当成实参传入到install方法的实参位置
*/

/*
  Vue2. 中如何定义全局指令?
   Vue.directive('指令名称', {
     inserted(el, binding) {
       el: 添加了指令的哪个dom元素
       binding.value: 指令=后面绑定的表达式
     }
   })
   使用指令: v-指令名称

  Vue3. 中如何定义全局指令?
    createApp -> app
    app.directive('指令名称', {
      mounted(el, binding) {
        el: 添加了指令的那个dom元素
        bingding.value: 指令=后面绑定的表达式的值
      }
    })
    使用指令: v-指令名称
*/

import { useIntersectionObserver } from '@vueuse/core'
const plugin = {
  install (app) {
    // 插件逻辑
    // console.log(app)
    app.directive('img-lazy', {
      mounted (el, binding) {
        // console.log(el, binding.value)
        // el: imgdom对象
        // binding.value: 图片的url地址
        // 图片懒加载具体实现
        // 核心思路: 进入到视口区域的图片才正式加载
        // 技术方案: 1.如何监控图片进入到了视口区域? 2.如何让图片发起正式请求 ?
        // 解决方案: 1.vueuse解决监听图片进入视口区域的问题 2.给img.src = 'url'
        const { stop } = useIntersectionObserver( // 三个参数
          el, // 第一参数
          ([{ isIntersecting }], observerElement) => {
            // isIntersecting: 进入为true 出去为false
            console.log(isIntersecting)
            // 监听持续都在 除非手动停止
            // 监听非常精确,不管哪个方向都可以监听到
            if (isIntersecting) {
              el.src = binding.value
              // 完成首次加载之后,停止监听
              stop()
            }
          },
          // 第三参数:被监听的元素进入多大面积开始执行回调
          // 0 ~ 1 值越小要求的面积就越小
          { threshold: 0 }
        )
      }
    })
  }
}

export default plugin
